/**
 * Created by Administrator on 2017/4/20.
 */


var Poker = require('../Poker/Poker');
var PokerRoom = require('../Poker/room').PokerRoom;

var Const = require('./const');
var SubCode = require('../subCode');

var RoundStatus = {
    'WAITING': 1,   // 等待其它玩家准备
    'PREPARE': 2,   // 准备人数足够，将继续等待，其它玩家依然可以准备
    'READY': 3,     // 就绪，开始游戏
    'ADDANTE': 4,   //加注
    'PLAY': 5,     // 玩家亮牌
}

exports.QZNNRoom = PokerRoom.extend({
    _roundStatus: RoundStatus.WAITING,

    _dealerIndex: 0,           // 庄家坐位
    _selectWaitTime: 0,        // 开始选牌的时间
    _waitRobTime: 0,            // 开始抢庄的时间
    _waitAddAnteTime: 0,        // 开始加注的时间
    _waitTimer: 0,              //计时器
    _statusStartTime: 0,
    _roundAnte: 0,              //本轮注数
    _roundWinPlayer: 0,         //本轮赢家
    _roundTurn: 0,
    init: function(rid, creator, msg) {
        this._super(rid, creator, msg);

        this._roundStatus = RoundStatus.WAITING;

        if (this.getOption("MS") == "FZZ") {
            this._dealerIndex = 1;
        } else {
            this._dealerIndex = 0;
        }
        this._waitTimer = 0;
        this._selectWaitTime = 0;
        this._roundAnte = 0;
        this._roundTurn = 0;
        this._statusStartTime = 0;
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getRoundInfo: function() {
        var info = this._super();
        info.robDealerWaitMS = this.getHideOption("robDealerWaitMS");
        info.selectWaitMS = this.getHideOption("selectWaitMS");
        return info;
    },
    getSettlementInfo: function(){
        var info = this._super();


        return info;
    },
    getReconnectInfo: function (rePlayer) {
        var info = this._super(rePlayer);
        info.dealer = this._dealerIndex;
        info.selectWaitTime = this._selectWaitTime;
        info.roundAnte = this._roundAnte;
        info.roundTurn = this._roundTurn;
        info.roundStatus = this._roundStatus;
        var waitTime = 0;
        if(this._roundStatus == RoundStatus.READY){
            waitTime = this.getHideOption("robDealerWaitMS");
        }else if(this._roundStatus == RoundStatus.ADDANTE){
            waitTime = this.getHideOption("addAnteWaitMS");
        }else if(this._roundStatus == RoundStatus.PLAY){
            waitTime = this.getHideOption("playWaitMS");
        }
        info.remainTime = 0;
        var now = new Date().getTime();
        if(now - this._statusStartTime <= waitTime){
            info.remainTime = waitTime - (now - this._statusStartTime);
        }
        return info;
    },
    getRoomConfig: function (){
        var cfg = this._super();
        cfg.destroyWaitTime = 120;
        cfg.waitTimeoutTime = 90;
        cfg.resetDestroyOnNewRound = 0;
        return cfg;
    },
    onAfterPlayerReady: function(player) {
        this._super(player);

        var subConfig = this.getSubConfig();

        if (!this.isPlaying() && this.getReadyPlayerCount() == this.getMaxPlayer()) {
            var enableStart = false;
            if (this.isSceneRoom()) {
                enableStart = true;
            } else if (this.isCardRoom()) {
                var creator = this.getPlayerByUid(this.getCreator());
                enableStart = (creator && creator.isReady()) ? true : false;
            }
            var allReady = true;
            this.enumPlayers(function(eIndex, ePlayer){
                if(!ePlayer.isReady()){
                    allReady = false;
                }
            });
            if (enableStart && allReady) {
                this._startNewRoundAfter(this.getHideOption("startWaitMS"));
            }
        }
    },

    onPlayerQuitRoom: function(player) {
        this._super(player);

        if (this._roundStatus != RoundStatus.PREPARE) {
            return;
        }

        if (this.getReadyPlayerCount() <= this.getSubConfig().roomPlayerMin) {
            this.broadcast("onCancelStartWait", {});
            this._roundStatus = RoundStatus.WAITING;
        }
    },

    checkStartNewRound: function() {
        if (this.isPlaying()) {
            return false;
        }

        if (this._roundStatus != RoundStatus.READY) {
            return false;
        }

        return true;
    },

    onBeforeStartNewRound: function() {
        this._super();
        this._selectWaitTime = 0;
        this._statusStartTime = 0;
        this._roundTurn = 0;
    },
    /*onBeforePlayerReady: function(player) {
        this._super(player);

        if (player == this.getPlayerByUid(this.getCreator())) {
            var subConfig = this.getSubConfig();
            if(this.getPlayerCount() >= subConfig.roomPlayerMin){
                if(this.getReadyPlayerCount() == (this.getPlayerCount() - 1)){
                    return Code.SUCCESS;
                }
                return SubCode.PLAYER_NOT_ALL_READY;
            }else {
                return SubCode.NOT_PLAYER;
            }
        }
        return Code.SUCCESS;
    },*/

    onAfterStartNewRound: function() {
        this._super();
        this._startPlay();
    },
    onDestroy: function() {
        this._super();
        if(this._waitTimer){
            clearTimeout(this._waitTimer);
        }
    },

    onSettlement: function() {
        this._super();
        if(this.getOption("MS") == "ZNMS"){
            this.enumPlaying(function(eIndex, ePlayer) {
                if(ePlayer._giveUp){
                    return;
                }
                if(eIndex == this._roundWinPlayer){
                    return;
                }
                if(this._roundWinPlayer){
                    if(ePlayer._compar(this._roundWinPlayer)){
                        this._roundWinPlayer = eIndex;
                    }
                }else{
                    this._roundWinPlayer = eIndex;
                }
                //ePlayer.settlementPattern();
            }.bind(this));
        }else{
            this.enumPlaying(function(eIndex, ePlayer) {
                ePlayer.settlementPattern();
            });
        }
    },

    onCurRoundFinished: function() {
        this._super();
        this._roundStatus = RoundStatus.WAITING;
        this._statusStartTime = 0;
        if(this._waitTimer){
            clearTimeout(this._waitTimer);
        }
    },

    /******************************************************************
     * 功能接口
     ******************************************************************/

    handleRobDealer: function(player, msg, callback) {
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }

        if (this.getOption("MS") != "KPQZ") {
            callback({code: SubCode.QZNN_MS_UNMATCH}); return;
        }

        if (player.getRobDealer() != -1) {
            callback({code: SubCode.QZNN_ROB_DEALER_SET}); return;
        }

        if (!msg.hasOwnProperty('value') || isNaN(msg.value)) {
            callback({code: Code.ARGS_INVALID}); return;
        }

        var value = parseInt(msg.value);
        if (value != 0 && value != 1) {
            callback({code: Code.ARGS_VALUE_WRONG}); return;
        }

        player.setRotDealer(value);
        this.broadcast("onPlayerRobDealer", {
            playerIndex: player.getIndex(),
            value: value
        });
        callback({});

        var isAllSet = true;
        this.enumPlaying(function(eIndex, ePlayer) {
            if (ePlayer.getRobDealer() == -1) {
                isAllSet = false;
            }
        });

        if (isAllSet) {
            this._dealRobDealerAllSet();
            //this._waitAddAnte();

        }
    },
    handlePlayCards : function (player, msg, callback) {
        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }
        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }
        if(player._playCards){
            callback({code: SubCode.QZNN_PLAY_CARD_END}); return;
        }
        callback({});
        player._playCards = true;
        player.settlementPattern();
        var resp = {
            playerIndex: player.getIndex(),
            handCards: player._handCards.getInitCards(),
            selectedCards: player._selectedCards,
            niu: player._stat.roundPattern
        };
        this.broadcast("onPlayCards", resp);
        var isAllPlayed = true;
        this.enumPlaying(function(eIndex, ePlayer) {
            if (ePlayer._playCards == false) {
                isAllPlayed = false;
            }
        });
        if (isAllPlayed) {
            //this.broadcast("onSelectCardsFinish", {});
            this.broadcast("onPlayCardsFinish", {});
            this.settlementCurRound(500);
        }
    },
    //加注
    handleAddAnte : function (player, msg, callback) {
        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }
        if (this.getOption("MS") == "TBMS") {
            callback({code: SubCode.QZNN_MS_UNMATCH}); return;
        }
        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }
        if (!msg.hasOwnProperty('num') || isNaN(msg.num)) {
            callback({code: Code.ARGS_INVALID}); return;
        }
        if(player.getAnte() && this.getOption("MS") != "ZNMS"){
            callback({code: SubCode.QZNN_ANTE_ADDED}); return;
        }
        if(this.getOption("MS") == "ZNMS") {
            if (msg.num < this._roundAnte) {
                callback({code: SubCode.QZNN_ANTE_ARG_ERROR}); return;
            }
            if(player._giveUp){
                callback({code: SubCode.QZNN_PLAYER_IS_GIVE_UP}); return;
            }
        }
        var addAnet = msg.num;
        if(this.getOption("MS") == "ZNMS") {
            if (addAnet > 500) {
                callback({code: SubCode.QZNN_ANTE_IS_MAX});
                return;
            }
            if (addAnet < this._roundAnte) {
                callback({code: SubCode.QZNN_ANTE_ARG_ERROR});
                return;
            }
            this._roundAnte = addAnet;
        }
        callback({});
        var ante = player.getAnte();
        if(this.getOption("MS") == "ZNMS") {
            if(player._lookCards){
                addAnet *= 2;
            }
        }
        player.setAnte(ante + addAnet);
        this.broadcast("onPlayerAddAnte", {
            playerIndex: player.getIndex(),
            num: addAnet
        });
        if(this.getOption("MS") == "ZNMS") {
            this._changeCurPlay();
        }else{
            var isAllAdded = true;
            var room = this;
            this.enumPlaying(function(eIndex, ePlayer) {
                if (ePlayer.getAnte() == 0 && eIndex != room._dealerIndex) {
                    isAllAdded = false;
                }
            });
            if (isAllAdded) {
                this.broadcast("onAddAnteFinish", {});
                this._waitPlayCards();
            }
        }
    },
    //看牌
    handleLookCards: function (player, msg, callback) {
        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }
        if (this.getOption("MS") != "ZNMS") {
            callback({code: SubCode.QZNN_MS_UNMATCH}); return;
        }
        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }
        if(player._giveUp){
            callback({code: SubCode.QZNN_PLAYER_IS_GIVE_UP}); return;
        }
        if(player._lookCards){
            callback({code: SubCode.QZNN_PLAYER_IS_LOOKED}); return;
        }
        callback({});

        player._lookCards = true;
        this.broadcast("onPlayerLookCards", {
            playerIndex: player.getIndex(),
        });
    },
    //跟注
    handleFollowAnte : function (player, msg, callback) {
        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING});
            return;
        }
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING});
            return;
        }
        if (this.getOption("MS") != "ZNMS") {
            callback({code: SubCode.QZNN_MS_UNMATCH});
            return;
        }
        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED});
            return;
        }
        if (player._giveUp) {
            callback({code: SubCode.QZNN_PLAYER_IS_GIVE_UP});
            return;
        }
        callback({});

        var ante = player.getAnte();
        var addAnet = this._roundAnte;
        if (player._lookCards) {
            addAnet *= 2;
        }
        player.setAnte(ante + addAnet);
        this.broadcast("onPlayerFollowAnte", {
            playerIndex: player.getIndex(),
            num: addAnet
        });
        this._changeCurPlay();

    },
    //弃牌
    handleGiveUp : function (player, msg, callback) {
        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }
        if (this.getOption("MS") != "ZNMS") {
            callback({code: SubCode.QZNN_MS_UNMATCH}); return;
        }
        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }
        if(player._giveUp){
            callback({code: SubCode.QZNN_PLAYER_IS_GIVE_UP}); return;
        }
        callback({});

        player._giveUp = true;
        //player.setPlaying(false);
        this.broadcast("onPlayerGiveUp", {
            playerIndex: player.getIndex(),
        });
        this._changeCurPlay();
    },
    //比牌
    handleComparCards : function (player, msg, callback) {
        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }
        if (this.getOption("MS") != "ZNMS") {
            callback({code: SubCode.QZNN_MS_UNMATCH}); return;
        }
        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }
        if(player._giveUp){
            callback({code: SubCode.QZNN_PLAYER_IS_GIVE_UP}); return;
        }
        if (!msg.hasOwnProperty('index') || isNaN(msg.index)) {
            callback({code: Code.ARGS_INVALID}); return;
        }
        var tempPlayer = this.getPlayerByIndex(msg.index);
        if(!tempPlayer.isPlaying()){
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }
        callback({});

        var ante = player.getAnte();
        var addAnet = this._roundAnte * 2;
        if (player._lookCards) {
            addAnet *= 2;
        }
        player.setAnte(ante + addAnet);
        var winPlayer = 0;
        if(player._compar(msg.index)){
            tempPlayer._giveUp = true;
            //tempPlayer.setPlaying(false);
            winPlayer = player.getIndex();
        }else{
            player._giveUp = true;
            //player.setPlaying(false);
            winPlayer = tempPlayer.getIndex();

        }
        this.broadcast("onPlayerComparCards", {
            playerIndex: player.getIndex(),
            ePlayerIndex: msg.index,
            num: addAnet,
            win: winPlayer

        });
        this._changeCurPlay();
    },
    //选牌（已废）
    handleSelectCards: function(player, msg, callback) {
        if (!msg.cards) {
            callback({code: Code.ARGS_INVALID}); return;
        }

        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }

        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }

        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }

        var cards = msg.cards;
        if (!ExObject.isArray(cards)) {
            callback({code: Code.ARGS_VALUE_WRONG}); return;
        }

        if (!player.setSelectedCards(cards)) {
            callback({code: SubCode.CARD_NOT_EXIST}); return;
        }

        callback({});

        this.broadcast("onPlayerSelectCards", {
            playerIndex: player.getIndex(),
            selectNum: msg.cards.length
        });

        var isAllSelected = true;
        this.enumPlaying(function(eIndex, ePlayer) {
            if (!ePlayer.isSelectedCards()) {
                isAllSelected = false;
            }
        });

        if (isAllSelected) {
            this.broadcast("onSelectCardsFinish", {});
            this.settlementCurRound(500);
        }
    },

    _startNewRoundAfter: function(timeMS) {
        if (this._roundStatus != RoundStatus.WAITING) {
            return;
        }

        this.broadcast("onRoomStartAfter", {
            time: timeMS,
        });

        this._roundStatus = RoundStatus.PREPARE;

        setTimeout(function() {
            if (this._roundStatus != RoundStatus.PREPARE) {
                return;
            }

            this._roundStatus = RoundStatus.READY;
            this.tryStartNewRound();
        }.bind(this), timeMS);
    },

    _startPlay: function() {
        this.initPlayersHandCards();
        if (this.getOption("MS") == "TBMS") {
            this._waitPlayCards();
        } else if(this.getOption("MS") == "ZNMS") {
            this._changeCurPlay(this._dealerIndex);
        }else if(this.getOption("MS") == "FZZ") {
            this._waitAddAnte();
        }else{
            this._waitRobDealer();
        }
    },

    _waitRobDealer: function() {
        this._waitRobTime = Date.getStamp();
        this.broadcast("onStartRobDealer", {
            waitRobTime: this.getHideOption("robDealerWaitMS")
        });
        if(this._waitTimer){
            clearTimeout(this._waitTimer);

        }
        this._statusStartTime = new Date().getTime();

        this._waitTimer = setTimeout(function() {
            if (!this.isPlaying()) {
                return;
            }

            if (this._roundStatus != RoundStatus.READY) {
                return;
            }

            this.enumPlaying(function(eIndex, ePlayer) {
                if (ePlayer.getRobDealer() == -1) {
                    ePlayer.setRotDealer(0);
                    this.broadcast("onPlayerRobDealer", {
                        playerIndex: ePlayer.getIndex(),
                        value: 0
                    });
                }
            }.bind(this));

            this._dealRobDealerAllSet();

        }.bind(this), this.getHideOption("robDealerWaitMS"));
    },

    _dealRobDealerAllSet: function() {
        var arr0 = [];
        var arr1 = [];

        this.enumPlaying(function(eIndex, ePlayer) {
            if (ePlayer.getRobDealer()) {
                arr1.push(eIndex);
            } else {
                arr0.push(eIndex);
            }
        });

        this._dealerIndex = Ext.randArray(arr1) || Ext.randArray(arr0);

        this.broadcast("onDealerChanged", {
            dealer: this._dealerIndex,
            players: arr0.length > 0 ? arr0 : arr1
        });
        this._waitAddAnte();
    },
    _waitAddAnte: function(){
        this._roundStatus = RoundStatus.ADDANTE;
        this._waitAddAnteTime = Date.getStamp();
        this.broadcast("onStartAddAnte", {
            waitAddAnteTime: this.getHideOption("addAnteWaitMS")
        });
        if(this._waitTimer){
            clearTimeout(this._waitTimer);
        }
        this._statusStartTime = new Date().getTime();

        this._waitTimer = setTimeout(function() {
            if (!this.isPlaying()) {
                return;
            }
            if (this._roundStatus != RoundStatus.ADDANTE) {
                return;
            }
            console.log("addAnteWaitMS = %d", this.getHideOption("addAnteWaitMS"));
            this.enumPlaying(function(eIndex, ePlayer) {
                if (ePlayer.getAnte() == 0 && eIndex != this._dealerIndex){
                    ePlayer.setAnte(10);
                    this.broadcast("onPlayerAddAnte", {
                        playerIndex: ePlayer.getIndex(),
                        num: 10
                    });
                }
            }.bind(this));
            this.broadcast("onAddAnteFinish", {});
            this._waitPlayCards();
        }.bind(this), this.getHideOption("addAnteWaitMS"));
    },
    _waitPlayCards: function() {
        var room = this;
        if(room.getOption("MS") == "KPQZ"){
            this.enumPlayers(function(eIndex, ePlayer){
                if(room._publicCards.isEmpty()) {
                    return;
                }
                var card = room._publicCards.getCard();
                /*if(eIndex == 1){
                 card = 112;
                 }else if(eIndex == 2){
                 card = 212;
                 }*/
                ePlayer.addNewCard(card);
                ePlayer._handCards.initCards.push(card);
                var resp = {
                    playerIndex: eIndex,
                    card: card,
                };
                ePlayer.send("onNewCard", resp);
            });
        }
        this.broadcast("onStartPlayCards", {
            playWaitTime: this.getHideOption("playWaitMS")
        });
        this._roundStatus = RoundStatus.PLAY;
        if(this._waitTimer){
            clearTimeout(this._waitTimer);

        }
        this._statusStartTime = new Date().getTime();

        this._waitTimer = setTimeout(function() {
            if (this._roundStatus != RoundStatus.PLAY) {
                return;
            }
            this.enumPlayers(function(eIndex, ePlayer){
                if(ePlayer._playCards == false){
                    ePlayer.settlementPattern();
                    var resp = {
                        playerIndex: ePlayer.getIndex(),
                        handCards: ePlayer._handCards.getInitCards(),
                        selectedCards: ePlayer._selectedCards,
                        niu: ePlayer._stat.roundPattern
                    };
                    this.broadcast("onPlayCards", resp);
                }
            }.bind(this));
            this.broadcast("onPlayCardsFinish", {});
            this.settlementCurRound();
        }.bind(this), this.getHideOption("playWaitMS"));
    },
    _waitSelectCards: function() {
        var room = this;
        this.enumPlayers(function(eIndex, ePlayer){
            if(room._publicCards.isEmpty()) {
                return;
            }
            var card = room._publicCards.getCard();
            ePlayer.addNewCard(card);
            ePlayer._handCards.initCards.push(card);
            var resp = {
                playerIndex: eIndex,
                card: card,
            };
            ePlayer.send("onNewCard", resp);
        });
        this._roundStatus = RoundStatus.PLAY;
        this._selectWaitTime = Date.getStamp();
        this.broadcast("onStartSelectCards", {
            selectWaitTime: this.getHideOption("selectWaitMS")
        });
        setTimeout(function() {
            if (this._roundStatus != RoundStatus.PLAY) {

                return;
            }
            this.broadcast("onSelectCardsFinish", {});
            this.settlementCurRound();
        }.bind(this), this.getHideOption("selectWaitMS"));
    },
    _changeCurPlay: function(index){
        if(this._getPlayingPlayerCount() == 1 || this._roundTurn >= 10){
            this.settlementCurRound();
        }else{
            if(index){
                this._curPlay = index;
            }else{
                this._curPlay = this._getNextPlayer(this._curPlay);
            }
            this._sendCurPlay();
        }
    },
    _getPlayingPlayerCount: function () {
        var count = 0;
        this.enumPlaying(function (eIndex, ePlayer) {
            if(ePlayer._giveUp){
                return;
            }
            count += 1;
        });
        return count;
    },
    _getNextPlayer: function (fromIndex) {
        if (fromIndex < 1 || fromIndex > this.getMaxPlayer()) {
            fromIndex = 1;
        }
        var tmpIndex = fromIndex;
        do {
            tmpIndex = this.getNextIndex(tmpIndex);
            if(tmpIndex == 1){
                this._roundTurn += 1;
            }
            var tmpPlayer = this.getPlayerByIndex(tmpIndex);
            if (tmpPlayer && tmpPlayer.isPlaying() && tmpPlayer._giveUp == false) {
                break;
            }
        } while (tmpIndex != fromIndex);

        return tmpIndex;
    },
    _sendCurPlay: function() {
        var msg = {
            'curPlay': this._curPlay,
        };
        this.broadcastReplay("onCurPlay", msg);
    },
});